package com.drelephant.commons.sdk;

import com.drelephant.commons.Constants;
import com.drelephant.commons.req.BaseChannelReq;
import com.drelephant.commons.util.BeanUtil;
import com.drelephant.commons.util.SignUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Map;

public class SecretSdk {

    public static String channelSign(BaseChannelReq<?> channelReq, String signType, String priKey, Charset charset) {
        Map<String, Object> channelReqMap = BeanUtil.beanToMap(channelReq.getReqData());
        channelReqMap.put("reqNo", channelReq.getReqNo());
        try {
            channelReqMap = SignUtil.byCode(signType).sign(channelReqMap, priKey, charset);
            channelReq.setSign(String.valueOf(channelReqMap.get("sign")));
            return JsonObjectMapperFactory.getInstance().writeValueAsString(channelReq);

        } catch (Exception e) {
            throw new RuntimeException("渠道加签错误 channelReqMap:" + channelReqMap + " , priKey:" + priKey, e);
        }

    }

    public static boolean verifySign(String channelSignJson, String signType, String pubkey, Charset charset) {
        try {
            BaseChannelReq<?> channelReq = JsonObjectMapperFactory.getInstance().readValue(channelSignJson,
                    BaseChannelReq.class);
            Map<String, Object> channelReqMap = BeanUtil.beanToMap(channelReq.getReqData());
            channelReqMap.put("reqNo", channelReq.getReqNo());
            return SignUtil.byCode(signType).verify(channelReqMap,
                    channelReq.getSign(), pubkey, charset);

        } catch (Exception e) {
            throw new RuntimeException("渠道验签错误 channelSignJson:" + channelSignJson + " , pubkey:" + pubkey, e);
        }

    }

    public static class JsonObjectMapperFactory {
        private static final String DATE_FORMAT = Constants.SHARE_DEFAULT_FORMAT;
        private static ObjectMapper om = new ObjectMapper();

        static {
            om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            om.setDateFormat(new SimpleDateFormat(DATE_FORMAT));
            om.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            om.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        }

        public static ObjectMapper getInstance() {
            return om;
        }
    }

}
